package org.daochong.lang.security;

import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.daochong.lang.BeanUtil;

public class CertificateRequest {

	public final static String OID_KeyUsage = "x509.info.extensions.KeyUsage";
	public final static String OID_SubjectKeyIdentifier = "x509.info.extensions.SubjectKeyIdentifier";
	public final static String OID_IssuerAlternativeName = "x509.info.extensions.IssuerAlternativeName";
	public final static String OID_CertificatePolicies = "x509.info.extensions.CertificatePolicies";
	public final static String OID_NameConstraints = "x509.info.extensions.NameConstraints";
	public final static String OID_PolicyConstraints = "x509.info.extensions.PolicyConstraints";
	public final static String OID_FreshestCRL = "x509.info.extensions.FreshestCRL";
	public final static String OID_CRLDistributionPoints = "x509.info.extensions.CRLDistributionPoints";
	public final static String OID_PrivateKeyUsage = "x509.info.extensions.PrivateKeyUsage";
	public final static String OID_CRLReasonCode = "x509.info.extensions.CRLReasonCode";
	public final static String OID_OCSPNoCheck = "x509.info.extensions.OCSPNoCheck";
	public final static String OID_SubjectInfoAccess = "x509.info.extensions.SubjectInfoAccess";
	public final static String OID_BasicConstraints = "x509.info.extensions.BasicConstraints";
	public final static String OID_DeltaCRLIndicator = "x509.info.extensions.DeltaCRLIndicator";
	public final static String OID_CRLNumber = "x509.info.extensions.CRLNumber";
	public final static String OID_NetscapeCertType = "x509.info.extensions.NetscapeCertType";
	public final static String OID_CertificateIssuer = "x509.info.extensions.CertificateIssuer";
	public final static String OID_ExtendedKeyUsage = "x509.info.extensions.ExtendedKeyUsage";
	public final static String OID_IssuingDistributionPoint = "x509.info.extensions.IssuingDistributionPoint";
	public final static String OID_InhibitAnyPolicy = "InhibitAnyPolicy";
	public final static String OID_AuthorityKeyIdentifier = "x509.info.extensions.AuthorityKeyIdentifier";
	public final static String OID_SubjectAlternativeName = "x509.info.extensions.SubjectAlternativeName";
	public final static String OID_AuthorityInfoAccess = "x509.info.extensions.AuthorityInfoAccess";
	public final static String OID_PolicyMappings = "x509.info.extensions.PolicyMappings";

	private String commonName;
	private String dept;
	private String organ;
	private String city;
	private String province;
	private String country = "CN";
	private String uid;
	private String street;
	private String title;
	private String ipAddress;
	private String domainComponent;
	private String dnq;
	private String surName;
	private String givenName;
	private String initials;
	private String generation;
	private String serialNumber;
	private String email;

	private int length = 1024;
	private int expiredDays = 365;
	private String alias;
	private List<String> authUrls;
	private List<String> crls;
	private List<String> newestCrls;
	private Map<String, String> data;

	public CertificateRequest() {

	}

	public CertificateRequest(String dn) {
		init(dn);
	}

	public CertificateRequest(X509Certificate cert) {
		init(cert.getIssuerDN().getName());
	}

	public List<String> getAuthUrls() {
		return authUrls;
	}

	public void setAuthUrls(List<String> authUrls) {
		this.authUrls = authUrls;
	}

	public void setAuthUrls(String authUrl) {
		if (this.authUrls == null) {
			this.authUrls = new ArrayList<String>();
		}
		this.authUrls.add(authUrl);
	}

	public String getAlias() {
		if (this.alias == null) {
			this.alias = BeanUtil.uuid();
		}
		return alias;
	}

	public String getCity() {
		return city;
	}

	public String getCommonName() {
		return this.commonName;
	}

	public String getCountry() {
		return country;
	}

	public List<String> getCrls() {
		return crls;
	}

	public Map<String, String> getData() {
		return data;
	}

	public String getDept() {
		return dept;
	}

	public String getDnq() {
		return dnq;
	}

	public String getDomainComponent() {
		return domainComponent;
	}

	public String getEmail() {
		return email;
	}

	public int getExpiredDays() {
		return expiredDays;
	}

	public String getGeneration() {
		return generation;
	}

	public String getGivenName() {
		return givenName;
	}

	public String getInitials() {
		return initials;
	}

	public String getIpAddress() {
		return ipAddress;
	}

	public int getLength() {
		return length;
	}

	public String getOrgan() {
		return organ;
	}

	public String getProvince() {
		return province;
	}

	public String getSerialNumber() {
		return serialNumber;
	}

	public String getStreet() {
		return street;
	}

	public String getSurName() {
		return surName;
	}

	public String getTitle() {
		return title;
	}

	public String getUid() {
		return uid;
	}

	private void init(String dn) {
		if (dn == null)
			return;
		for (String str : dn.split(",")) {
			str = str.trim();
			int pos = str.indexOf("=");
			if (pos == -1)
				continue;
			String key = str.substring(0, pos).trim();
			String value = str.substring(pos + 1).trim();
			if (key.equalsIgnoreCase("CN")) {
				this.commonName = value;
			} else if (key.equalsIgnoreCase("OU")) {
				this.dept = value;
			} else if (key.equalsIgnoreCase("O")) {
				this.organ = value;
			} else if (key.equalsIgnoreCase("L")) {
				this.city = value;
			} else if (key.equalsIgnoreCase("ST") || key.equalsIgnoreCase("S")) {
				this.province = value;
			} else if (key.equalsIgnoreCase("C")) {
				this.country = value;
			} else if (key.equalsIgnoreCase("UID")) {
				this.uid = value;
			} else if (key.equalsIgnoreCase("STREET")) {
				this.street = value;
			} else if (key.equalsIgnoreCase("T")) {
				this.title = value;
			} else if (key.equalsIgnoreCase("IP")) {
				this.ipAddress = value;
			} else if (key.equalsIgnoreCase("DC")) {
				this.domainComponent = value;
			} else if (key.equalsIgnoreCase("DNQUALIFIER") || key.equalsIgnoreCase("DNQ")) {
				this.dnq = value;
			} else if (key.equalsIgnoreCase("GIVENNAME")) {
				this.givenName = value;
			} else if (key.equalsIgnoreCase("INITIALS")) {
				this.initials = value;
			} else if (key.equalsIgnoreCase("GENERATION")) {
				this.generation = value;
			} else if (key.equalsIgnoreCase("SERIALNUMBER")) {
				this.serialNumber = value;
			} else if (key.equalsIgnoreCase("EMAIL") || key.equalsIgnoreCase("EMAILADDRESS")) {
				this.email = value;
			}
		}
	}

	public void setAlias(String alias) {
		this.alias = alias;
	}

	public List<String> getNewestCrls() {
		return newestCrls;
	}

	public void setNewestCrls(List<String> newestCrls) {
		if (this.newestCrls == null) {
			this.newestCrls = newestCrls;
		} else {
			this.newestCrls.addAll(newestCrls);
		}
	}

	public void setNewestCrls(String newestCrls) {
		if (this.newestCrls == null) {
			this.newestCrls = new ArrayList<String>();
		}
		this.newestCrls.add(newestCrls);
	}

	public void setCity(String city) {
		this.city = city;
	}

	public void setCommonName(String commonName) {
		this.commonName = commonName;
	}

	public void setCountry(String country) {
		this.country = country;
	}

	public void setCrls(List<String> crls) {
		if (this.crls == null) {
			this.crls = crls;
		} else {
			this.crls.addAll(crls);
		}
	}

	public void setCrls(String crl) {
		if (this.crls == null) {
			this.crls = new ArrayList<String>();
		}
		this.crls.add(crl);
	}

	public void setData(Map<String, String> data) {
		this.data = data;
	}

	public void setData(String key, String value) {
		if (this.data == null) {
			this.data = new LinkedHashMap<String, String>();
		}
		this.data.put(key, value);
	}

	public void setDept(String dept) {
		this.dept = dept;
	}

	public void setDnq(String dnq) {
		this.dnq = dnq;
	}

	public void setDomainComponent(String domainComponent) {
		this.domainComponent = domainComponent;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public void setExpiredDays(int expiredDays) {
		this.expiredDays = expiredDays;
	}

	public void setGeneration(String generation) {
		this.generation = generation;
	}

	public void setGivenName(String givenName) {
		this.givenName = givenName;
	}

	public void setInitials(String initials) {
		this.initials = initials;
	}

	public void setIpAddress(String ipAddress) {
		this.ipAddress = ipAddress;
	}

	public void setLength(int length) {
		this.length = length;
	}

	public void setOrgan(String organ) {
		this.organ = organ;
	}

	public void setProvince(String province) {
		this.province = province;
	}

	public void setSerialNumber(String serialNumber) {
		this.serialNumber = serialNumber;
	}

	public void setStreet(String street) {
		this.street = street;
	}

	public void setSurName(String surName) {
		this.surName = surName;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public void setUid(String uid) {
		this.uid = uid;
	}

	public String toX500Name() {
		String dn = "";
		if (uid != null) {
			dn += "UID=" + uid + ", ";
		}
		if (this.street != null) {
			dn += "STREET=" + this.street + ", ";
		}
		if (this.commonName != null) {
			dn += "CN=" + this.commonName + ", ";
		}
		if (dept != null) {
			dn += "OU=" + dept + ", ";
		}
		if (organ != null) {
			dn += "O=" + organ + ", ";
		}
		if (street != null) {
			dn += "STREET=" + street + ", ";
		}
		if (city != null) {
			dn += "L=" + city + ", ";
		}
		if (province != null) {
			dn += "ST=" + province + ", ";
		}
		if (country != null) {
			dn += "C=" + country + ", ";
		}
		if (title != null) {
			dn += "T=" + title + ", ";
		}
		if (ipAddress != null) {
			dn += "IP=" + ipAddress + ", ";
		}
		if (domainComponent != null) {
			dn += "DC=" + domainComponent + ", ";
		}
		if (dnq != null) {
			dn += "DNQ=" + dnq + ", ";
		}
		if (surName != null) {
			dn += "SURNAME=" + surName + ", ";
		}
		if (givenName != null) {
			dn += "GIVENNAME=" + givenName + ", ";
		}
		if (initials != null) {
			dn += "INITIALS=" + initials + ", ";
		}
		if (generation != null) {
			dn += "GENERATION=" + generation + ", ";
		}
		if (this.serialNumber != null) {
			dn += "SERIALNUMBER=" + serialNumber + ", ";
		}
		if (this.email != null) {
			dn += "EMAIL=" + this.email + ", ";
		}
		if (this.data != null) {
			for (String key : this.data.keySet()) {
				dn += key + "=" + this.data.get(key) + ", ";
			}
		}
		if (dn.endsWith(", ")) {
			dn = dn.substring(0, dn.length() - 2);
		}
		return dn;
	}

}
